home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Contributions / Olaf_Barthel / Tools / Debugging / Blowup / Source / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-27  |  8.2 KB  |  428 lines

  1. /*
  2.  * $Id: main.c 1.8 1999/06/27 09:52:19 olsen Exp olsen $
  3.  *
  4.  * :ts=4
  5.  *
  6.  * Blowup -- Catches and displays task errors
  7.  *
  8.  * Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
  9.  * Public Domain
  10.  */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "global.h"
  14. #endif    /* _GLOBAL_H */
  15.  
  16. /******************************************************************************/
  17.  
  18. #include "Blowup_rev.h"
  19.  
  20. /******************************************************************************/
  21.  
  22. #include "blowupsemaphore.h"
  23.  
  24. /******************************************************************************/
  25.  
  26. const STRPTR VersTag = VERSTAG;
  27.  
  28. /******************************************************************************/
  29.  
  30. STATIC BOOL ShowBannerMessage = TRUE;
  31.  
  32. /******************************************************************************/
  33.  
  34. STATIC struct BlowupSemaphore *    BlowupSemaphore;
  35. STATIC BOOL                        BlowupSemaphoreCreated;
  36.  
  37. /******************************************************************************/
  38.  
  39. STATIC struct BlowupSemaphore *
  40. FindBlowupSemaphore(VOID)
  41. {
  42.     struct BlowupSemaphore * bs;
  43.  
  44.     /* look for the semaphore; this call must be made under Forbid() */
  45.     bs = (struct BlowupSemaphore *)FindSemaphore(BLOWUPSEMAPHORENAME);
  46.  
  47.     return(bs);
  48. }
  49.  
  50. STATIC VOID
  51. DeleteBlowupSemaphore(struct BlowupSemaphore * bs)
  52. {
  53.     if(bs != NULL)
  54.     {
  55.         Forbid();
  56.  
  57.         /* gain exclusive access to the semaphore and remove it */
  58.         RemSemaphore((struct SignalSemaphore *)bs);
  59.  
  60.         ObtainSemaphore((struct SignalSemaphore *)bs);
  61.         ReleaseSemaphore((struct SignalSemaphore *)bs);
  62.  
  63.         Permit();
  64.  
  65.         /* release the memory allocated for the semaphore */
  66.         FreeMem(bs,sizeof(*bs));
  67.     }
  68. }
  69.  
  70. STATIC struct BlowupSemaphore *
  71. CreateBlowupSemaphore(VOID)
  72. {
  73.     struct BlowupSemaphore * bs;
  74.  
  75.     /* allocate memory for the semaphore and initialize it */
  76.     bs = AllocMem(sizeof(*bs),MEMF_ANY|MEMF_PUBLIC|MEMF_CLEAR);
  77.     if(bs != NULL)
  78.     {
  79.         bs->bs_SignalSemaphore.ss_Link.ln_Name    = bs->bs_SemaphoreName;
  80.         bs->bs_SignalSemaphore.ss_Link.ln_Pri    = 1;
  81.  
  82.         bs->bs_Version = BLOWUPSEMAPHOREVERSION;
  83.  
  84.         strcpy(bs->bs_SemaphoreName,BLOWUPSEMAPHORENAME);
  85.  
  86.         bs->bs_Owner        = FindTask(NULL);
  87.         bs->bs_ARegCheck    = &ARegCheck;
  88.         bs->bs_DRegCheck    = &DRegCheck;
  89.         bs->bs_StackCheck    = &StackCheck;
  90.         bs->bs_StackLines    = &StackLines;
  91.  
  92.         /* add the semaphore to the public list */
  93.         AddSemaphore((struct SignalSemaphore *)bs);
  94.     }
  95.  
  96.     return(bs);
  97. }
  98.  
  99. /******************************************************************************/
  100.  
  101. STATIC VOID
  102. Cleanup(VOID)
  103. {
  104.     /* delete the semaphore, if we created it */
  105.     if(BlowupSemaphoreCreated)
  106.     {
  107.         DeleteBlowupSemaphore(BlowupSemaphore);
  108.         BlowupSemaphore = NULL;
  109.     }
  110.  
  111.     /* release the semaphore; this is done only if we did
  112.      * not create the semaphore ourselves
  113.      */
  114.     if(BlowupSemaphore != NULL)
  115.     {
  116.         ReleaseSemaphore((struct SignalSemaphore *)BlowupSemaphore);
  117.         BlowupSemaphore = NULL;
  118.     }
  119.  
  120.     /* shut down the timer */
  121.     DeleteTimer();
  122.  
  123.     /* close intuition.library */
  124.     if(IntuitionBase != NULL)
  125.     {
  126.         CloseLibrary(IntuitionBase);
  127.         IntuitionBase = NULL;
  128.     }
  129.  
  130.     /* close utility.library, if this is necessary */
  131.     #if !defined(__SASC) || defined(_M68020)
  132.     {
  133.         if(UtilityBase != NULL)
  134.         {
  135.             CloseLibrary(UtilityBase);
  136.             UtilityBase = NULL;
  137.         }
  138.     }
  139.     #endif
  140. }
  141.  
  142. STATIC BOOL
  143. Setup(BOOL * offPtr)
  144. {
  145.     LONG error = OK;
  146.     int i;
  147.  
  148.     (*offPtr) = FALSE;
  149.  
  150.     /* Kickstart 2.04 or higher required */
  151.     if(SysBase->LibNode.lib_Version < 37)
  152.     {
  153.         const STRPTR message = "This program requires Kickstart 2.04 or better.\n";
  154.  
  155.         Write(Output(),message,strlen(message));
  156.         return(FAILURE);
  157.     }
  158.  
  159.     /* determine the program name */
  160.     StrcpyN(sizeof(ProgramName),ProgramName,VERS);
  161.  
  162.     for(i = strlen(ProgramName) - 1 ; i >= 0 ; i--)
  163.     {
  164.         if(ProgramName[i] == ' ')
  165.         {
  166.             ProgramName[i] = '\0';
  167.             break;
  168.         }
  169.     }
  170.  
  171.     /* set up the busy semaphore */
  172.     InitSemaphore(&BusySemaphore);
  173.  
  174.     /* open intuition.library */
  175.     IntuitionBase = OpenLibrary("intuition.library",37);
  176.     if(IntuitionBase == NULL)
  177.     {
  178.         Printf("%s: Could not open intuition.library V37.\n",ProgramName);
  179.         return(FAILURE);
  180.     }
  181.  
  182.     /* open utility.library, if this is necessary */
  183.     #if !defined(__SASC) || defined(_M68020)
  184.     {
  185.         UtilityBase = OpenLibrary("utility.library",37);
  186.         if(UtilityBase == NULL)
  187.         {
  188.             Printf("%s: Could not open utility.library V37.\n",ProgramName);
  189.             return(FAILURE);
  190.         }
  191.     }
  192.     #endif
  193.  
  194.     /* allocate the timer data */
  195.     if(CreateTimer() == -1)
  196.     {
  197.         Printf("%s: Could not create timer.\n",ProgramName);
  198.         return(FAILURE);
  199.     }
  200.  
  201.     /* initialize default options */
  202.     DRegCheck    = FALSE;
  203.     ARegCheck    = FALSE;
  204.     StackCheck    = FALSE;
  205.     StackLines    = 2;
  206.  
  207.     /* rendezvous with the global semaphore or create it */
  208.     Forbid();
  209.  
  210.     BlowupSemaphore = FindBlowupSemaphore();
  211.     if(BlowupSemaphore != NULL)
  212.     {
  213.         ObtainSemaphore((struct SignalSemaphore *)BlowupSemaphore);
  214.     }
  215.     else
  216.     {
  217.         BlowupSemaphore = CreateBlowupSemaphore();
  218.         if(BlowupSemaphore != NULL)
  219.         {
  220.             BlowupSemaphoreCreated = TRUE;
  221.         }
  222.         else
  223.         {
  224.             error = ERROR_NO_FREE_STORE;
  225.         }
  226.     }
  227.  
  228.     Permit();
  229.  
  230.     if(error == OK)
  231.     {
  232.         struct RDArgs * rda;
  233.  
  234.         /* these are the command line parameters, later
  235.          * filled in by ReadArgs() below
  236.          */
  237.         struct
  238.         {
  239.             SWITCH    Off;
  240.             SWITCH    Parallel;
  241.             SWITCH    NoBanner;
  242.             SWITCH    DRegCheck;
  243.             SWITCH    NoDRegCheck;
  244.             SWITCH    ARegCheck;
  245.             SWITCH    NoARegCheck;
  246.             SWITCH    StackCheck;
  247.             SWITCH    NoStackCheck;
  248.             NUMBER    StackLines;
  249.         } params;
  250.  
  251.         /* this is the command template, as required by ReadArgs() below;
  252.          * its contents must match the "params" data structure above
  253.          */
  254.         const STRPTR cmdTemplate =
  255.             "QUIT=OFF/S,"
  256.             "PARALLEL/S,"
  257.             "QUIET=NOBANNER/S,"
  258.             "DREGCHECK/S,"
  259.             "NODREGCHECK/S,"
  260.             "AREGCHECK/S,"
  261.             "NOAREGCHECK/S,"
  262.             "STACKCHECK/S,"
  263.             "NOSTACKCHECK/S,"
  264.             "STACKLINES/K/N";
  265.  
  266.         memset(¶ms,0,sizeof(params));
  267.  
  268.         /* read the command line parameters */
  269.         rda = ReadArgs((STRPTR)cmdTemplate,(LONG *)¶ms,NULL);
  270.         if(rda != NULL)
  271.         {
  272.             struct BlowupSemaphore * bs = BlowupSemaphore;
  273.  
  274.             /* shut down Blowup? */
  275.             if(params.Off)
  276.             {
  277.                 if(NOT BlowupSemaphoreCreated)
  278.                 {
  279.                     Signal(bs->bs_Owner,SIG_Stop);
  280.                 }
  281.  
  282.                 (*offPtr) = TRUE;
  283.             }
  284.  
  285.             /* enable parallel port output? */
  286.             if(params.Parallel)
  287.             {
  288.                 ChooseParallelOutput();
  289.             }
  290.  
  291.             /* do not show the banner message? */
  292.             if(params.NoBanner)
  293.             {
  294.                 ShowBannerMessage = FALSE;
  295.             }
  296.  
  297.             /* enable data register check? */
  298.             if(params.DRegCheck)
  299.             {
  300.                 (*bs->bs_DRegCheck) = TRUE;
  301.             }
  302.  
  303.             /* disable data register check? */
  304.             if(params.NoDRegCheck)
  305.             {
  306.                 (*bs->bs_DRegCheck) = FALSE;
  307.             }
  308.  
  309.             /* enable address register check? */
  310.             if(params.ARegCheck)
  311.             {
  312.                 (*bs->bs_ARegCheck) = TRUE;
  313.             }
  314.  
  315.             /* disable address register check? */
  316.             if(params.NoARegCheck)
  317.             {
  318.                 (*bs->bs_ARegCheck) = FALSE;
  319.             }
  320.  
  321.             /* enable stack check? */
  322.             if(params.StackCheck)
  323.             {
  324.                 (*bs->bs_StackCheck) = TRUE;
  325.             }
  326.  
  327.             /* disable stack check? */
  328.             if(params.NoStackCheck)
  329.             {
  330.                 (*bs->bs_StackCheck) = FALSE;
  331.             }
  332.  
  333.             /* set the number of stack lines to display? */
  334.             if(params.StackLines != NULL)
  335.             {
  336.                 LONG value;
  337.  
  338.                 value = (*params.StackLines);
  339.                 if(value < 0)
  340.                     value = 0;
  341.  
  342.                 (*bs->bs_StackLines) = value;
  343.             }
  344.  
  345.             FreeArgs(rda);
  346.         }
  347.         else
  348.         {
  349.             error = IoErr();
  350.         }
  351.     }
  352.  
  353.     if(error == OK)
  354.     {
  355.         return(SUCCESS);
  356.     }
  357.     else
  358.     {
  359.         PrintFault(error,ProgramName);
  360.  
  361.         return(FAILURE);
  362.     }
  363. }
  364.  
  365. /******************************************************************************/
  366.  
  367. int
  368. main(
  369.     int        argc,
  370.     char **    argv)
  371. {
  372.     int result = RETURN_FAIL;
  373.     BOOL switchedOff;
  374.  
  375.     /* set up all the data we need */
  376.     if(Setup(&switchedOff))
  377.     {
  378.         result = RETURN_OK;
  379.  
  380.         if(NOT switchedOff)
  381.         {
  382.             /* do something useful if we are the owner of the semaphore */
  383.             if(BlowupSemaphoreCreated)
  384.             {
  385.                 BOOL done;
  386.             
  387.                 /* show the welcome message */
  388.                 if(ShowBannerMessage)
  389.                 {
  390.                     DPrintf("%s -- Catches and displays task errors\n",ProgramName);
  391.                     DPrintf("Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>\n");
  392.                     DPrintf("Public Domain\n");
  393.                 }
  394.  
  395.                 Forbid();
  396.  
  397.                 /* plant the monitoring patches */
  398.                 AddPatches();
  399.  
  400.                 done = FALSE;
  401.                 do
  402.                 {
  403.                     /* wait for something to happen */
  404.                     if(FLAG_IS_SET(Wait(SIG_Stop),SIG_Stop))
  405.                     {
  406.                         done = TRUE;
  407.  
  408.                         /* wait until it is safe to quit */
  409.                         ObtainSemaphore(&BusySemaphore);
  410.  
  411.                         DPrintf("%s terminated.\n",ProgramName);
  412.                     }
  413.                 }
  414.                 while(NOT done);
  415.  
  416.                 /* remove the patches again */
  417.                 RemovePatches();
  418.  
  419.                 Permit();
  420.             }
  421.         }
  422.     }
  423.  
  424.     Cleanup();
  425.  
  426.     return(result);
  427. }
  428.